package com.springtest;

import java.text.SimpleDateFormat;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;


public class CompletableFutureDemo {


    public static void main(String[] args) throws ExecutionException,InterruptedException {

        //获取开始时间（用来统计程序运行时常）
        long t1 = System.currentTimeMillis();

        //同步方式
       //  notAsync();

        //异步方式
        async();

        //获取结束时间（用来统计程序运行时常）
        long t2 = System.currentTimeMillis();
        System.out.println("Main 运行时间 ：" + (t2-t1)/1000+"秒");
    }

    public static void notAsync(){
        System.out.println("---------------------------notAsync方法开始运行-----------------------------");
        //获取开始时间（用来统计程序运行时常）
        long t1 = System.currentTimeMillis();
        System.out.println("notAsync方法开始运行。。。。。");
        System.out.println("开始时间 :" + dateFormat(t1));

        int callSum1 = call1(1, 2);
        int callSum2 = call2(3,4);
        run1(3,4);
        run2(3,4);

        //获取结束时间（用来统计程序运行时常）
        long t2 = System.currentTimeMillis();
        System.out.println("结束时间 :" + dateFormat(t2));

        System.out.println("---------------------------notAsync方法运行结束-----------------------------");
        System.out.println("运行时间 ：" + (t2-t1)/1000+"秒");
    }

    public static void async() throws ExecutionException ,InterruptedException{
        System.out.println("---------------------------async方法开始运行-----------------------------");
        //异步方法 有返回值一 (均采用默认线程池)
        CompletableFuture<Integer> callFuture1 = CompletableFuture.supplyAsync(()->call1(1, 2));
        //异步方法 有返回值二
        CompletableFuture<Integer> callFuture2 = CompletableFuture.supplyAsync(()->call2(3,4));
        //异步方法 无返回值一
        CompletableFuture runFuture1 = CompletableFuture.runAsync(()->run1(3,4));
        //异步方法 无返回值二
        CompletableFuture runFuture2 = CompletableFuture.runAsync(()->run2(3,4));
        //allOf()：当所有给定的 CompletableFuture 完成时，返回一个新的 CompletableFuture
        //anyOf()：当任何一个给定的CompletablFuture完成时，返回一个新的CompletableFuture

        CompletableFuture.allOf(callFuture1, callFuture2,runFuture1, runFuture2);

        //获取返回结果
        callFuture1.get();
        //获取返回结果
        callFuture2.get();
        //获取返回结果
        runFuture1.get();
        //获取返回结果
        runFuture2.get();

        System.out.println("---------------------------async方法结束运行-----------------------------");
    }

    private static Integer call1(Integer num1, Integer num2) {
        long t1 = System.currentTimeMillis();
        try {
            Thread.sleep(30000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int sum = num1 + num2;
        long t2 = System.currentTimeMillis();
        System.out.println("有返回值--》supplyAsync--》call1  睡眠时间：" + (t2-t1)/1000+"秒  运行结果："+ sum);
        return sum;
    }

    private static Integer call2(int num1, int num2) {
        long t1 = System.currentTimeMillis();
        try {
            Thread.sleep(20000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int sum = num1 + num2;
        long t2 = System.currentTimeMillis();
        System.out.println("有返回值--》supplyAsync--》call2  睡眠时间：" + (t2-t1)/1000+"秒  运行结果："+ sum);
        return sum;
    }

    private static void run1(int num1, int num2) {
        long t1 = System.currentTimeMillis();
        try {
            Thread.sleep(20000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int sum = num1 + num2;
        long t2 = System.currentTimeMillis();
        System.out.println("无返回值--》runAsync--》run1  睡眠时间：" + (t2-t1)/1000+"秒  运行结果："+ sum);
    }

    private static void run2(int num1, int num2) {
        long t1 = System.currentTimeMillis();
        try {
            Thread.sleep(20000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int sum = num1 + num2;
        long t2 = System.currentTimeMillis();
        System.out.println("无返回值--》runAsync--》run2  睡眠时间：" +(t2-t1)/1000+"秒  运行结果："+ sum);
    }


    public static String dateFormat(long l){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sdf.format(l);
        return format;
    }
}

